#include <stdlib.h>

#include "cpu/register.h"
#include "memory/instruction.h"

//是一个struct数组
inst_t program[15] = 
{ 
    // uint64_t add(uint64_t, uint64_t)，即add函数的指令集
    {
        push_reg,
        {   REG,    0,  0,  (uint64_t *)&reg.rbp,   NULL  },
        {   EMPTY,  0,  0,  NULL,                   NULL  },
        "push   \%rbp"                                     //'\'是转义符号，如果不加转义符号的话，那么printf的时候会识别为%r
    },
    {
        mov_reg_reg,
        {   REG,  0,  0,  (uint64_t *)&reg.rsp,     NULL  },
        {   REG,  0,  0,  (uint64_t *)&reg.rbp,     NULL  },
        "mov    \%rsp,\%rbp"
    },
    {
        mov_reg_mem,
        {   REG,  0,  0,  (uint64_t *)&reg.rdi,     NULL  },
        {   MM_IMM_REG,  -0x18,  0,  (uint64_t *)&reg.rbp,     NULL  },    
        "mov    \%rdi,-0x18(\%rbp)"      //进行了一次访存，针对于MM：立即数是-0x18，寄存器是%rbp
    },
    {
        mov_reg_mem,
        {   REG,  0,  0,  (uint64_t *)&reg.rsi,     NULL  },
        {   MM_IMM_REG,  -0x20,  0,  (uint64_t *)&reg.rbp,     NULL  },
        "mov    \%rsi,-0x20(\%rbp)"
    },
    {
        mov_mem_reg,
        {   MM_IMM_REG,  -0x18,  0,  (uint64_t *)&reg.rbp,     NULL  },
        {   REG,  0,  0,  (uint64_t *)&reg.rdx,     NULL  },
        "mov    -0x18(\%rbp),\%rdx"
    },
    {
        mov_mem_reg,
        {   MM_IMM_REG,  -0x20,  0,  (uint64_t *)&reg.rbp,     NULL  },
        {   REG,  0,  0,  (uint64_t *)&reg.rax,     NULL  },
        "mov    -0x20(\%rbp),\%rax"
    },
    {
        add_reg_reg,
        {   REG,  0,  0,  (uint64_t *)&reg.rdx,     NULL  },
        {   REG,  0,  0,  (uint64_t *)&reg.rax,     NULL  },
        "add    \%rdx,\%rax"
    },
    {
        mov_reg_mem,
        {   REG,  0,  0,  (uint64_t *)&reg.rax,     NULL  },
        {   MM_IMM_REG,  -0x8,  0,  (uint64_t *)&reg.rbp,     NULL  },
        "mov    \%rax,-0x8(\%rbp)"
    },
    {
        mov_mem_reg,
        {   MM_IMM_REG,  -0x8,  0,  (uint64_t *)&reg.rbp,     NULL  },
        {   REG,  0,  0,  (uint64_t *)&reg.rax,     NULL  },
        "mov    -0x8(\%rbp),\%rax"
    },
    {
        pop_reg,
        {   REG,    0,  0,  (uint64_t *)&reg.rbp,   NULL  },
        {   EMPTY,  0,  0,  NULL,                   NULL  },
        "pop   \%rbp"
    },
    {
        ret,
        {   EMPTY,  0,  0,  NULL,   NULL  },
        {   EMPTY,  0,  0,  NULL,   NULL  },
        "retq"
    },
    // main entry point    add函数在main函数中的入口点
    {
        mov_reg_reg,
        { REG, 0, 0, &reg.rdx, NULL },
        { REG, 0, 0, &reg.rsi, NULL },
        "mov    \%rdx,\%rsi"
    },
    {
        mov_reg_reg,
        {   REG,  0,  0,  (uint64_t *)&reg.rax,     NULL  },
        {   REG,  0,  0,  (uint64_t *)&reg.rdi,     NULL  },
        "mov    \%rax,\%rdi"
    },
    { // reg.rip
        call,
        {   IMM,    (uint64_t)&(program[0]),  0,  NULL,     NULL  },
        {   EMPTY,  0,  0,  NULL,     NULL  },
        "callq  <add>"      //其实是call了一个地址，call了add函数的起始地址，也就是第一个操作数，也就是push_reg
    },
    { // return address
        mov_reg_mem,
        {   REG,  0,  0,  (uint64_t *)&reg.rax,     NULL  },
        {   MM_IMM_REG,  -0x8,  0,  (uint64_t *)&reg.rbp,     NULL  },
        "mov    \%rax,-0x8(\%rbp)"
    }
};